package humynn.engine
{
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	/**
	 * The Renderer handles all drawing related functions.
	 */
	public class Renderer
	{
		private var _target:BitmapData;
		private var _buffer:BitmapData;
		
		private var _locked:Boolean;
		
		public function Renderer(target:BitmapData)
		{
			_target = target;
			_buffer = new BitmapData(target.width, target.height, true, 0x00000000);
			
			_locked = false;
		}
		
		/**
		 * Prepares the buffer for drawing operations.
		 * Must be called before endDraw.
		 * 
		 * @param fillColor The color used to fill the render buffer.
		 * 
		 * @see endDraw
		 */
		public function beginDraw(fillColor:uint):void
		{
			_buffer.fillRect(_buffer.rect, fillColor);
			
			if(_locked)
			{
				trace("Please call endDraw after each beginDraw.");
				return;
			}
			
			_locked = true;
			_buffer.lock();
		}
		
		/**
		 * Ends the drawing cycle and copies the buffer to the display.
		 * Must be called after beginDraw
		 * 
		 * @see beginDraw
		 */
		public function endDraw():void
		{
			if(!_locked)
			{
				trace("Please call beginDraw before each endDraw.");
				return;
			}
			
			_buffer.unlock();
			_locked = false;
			
			_target.copyPixels(_buffer, _buffer.rect, new Point(0, 0));
		}
		
		/**
		 * Draws a BitmapData item to the buffer.
		 * 
		 * @param item The item to be drawn to the buffer.
		 * @param x The horizontal position of the left edge in relation to the buffer.
		 * @param y The vertical position of the top edge in relation to the buffer.
		 */
		public function draw(file:String, animIndex:uint = 0, animFrame:uint = 0, x:Number = 0, y:Number = 0, scale:Point = null, rotation:Number = 0, hFlip:Boolean = false):void
		{
			var item:BitmapData = ImageManager.getBitmapData(file, animIndex, animFrame);
			
			if(item == null)
			{
				trace("Invalid BitmapData.");
				return;
			}
			
			if(!_locked)
			{
				trace("Please call beginDraw before you call draw.");
				return;
			}
			
			var matrix:Matrix = new Matrix();
			
			if(hFlip)
			{
				matrix.scale(-1, 1);
				matrix.translate(item.width, 0);
			}
			
			if(scale != null)
			{
				matrix.scale(scale.x, scale.y);
			}
			
			matrix.translate(0 - (item.width / 2), 0 - (item.height / 2));
			matrix.rotate(rotation);
			matrix.translate((item.width / 2), (item.height / 2));
			
			matrix.translate(x, y);
			
			_buffer.draw(item, matrix);
		}
		
		/**
		 * Draws bitmap data straight to the buffer.
		 * 
		 * @param item The BitmapData to draw to the buffer.
		 * @param x The x location to draw to.
		 * @param y The y location to draw to.
		 */
		public function drawBmp(item:BitmapData, x:int = 0, y:int = 0):void
		{
			if(item == null)
			{
				trace("Invalid BitmapData.");
				return;
			}
			
			if(!_locked)
			{
				trace("Please call beginDraw before you call draw.");
				return;
			}
			
			_buffer.copyPixels(item, item.rect, new Point(x, y), null, null, true);
		}
	}
}